#include "phrase.h"

namespace  IAlib
{

Phrase::Phrase()
{
	m_parent = NULL;
}

Phrase::Phrase(const Phrase &phrase)
{
    m_id = phrase.getId();
    m_role = phrase.getRole();
    m_inform = phrase.m_inform;
    m_text = phrase.getText();
    m_precondition = phrase.m_precondition;
    QList<Phrase*> list = phrase.getChildren();
    m_associated_role_type = phrase.m_associated_role_type;
    m_associated_role = phrase.m_associated_role;
    for(int i = 0; i < list.size(); i++)
    {
        Phrase * new_phrase = new Phrase(*list[i]);
		new_phrase->setParent(this);
        m_children.append(new_phrase);
    }
}

Phrase::~Phrase()
{
    Phrase * parent = getParent();
    if (parent != NULL)
    {
        parent->removeChild(getId());
    }
    for (int i = 0; i < m_children.size(); i++)
    {
        delete(m_children[i]);
    }
}

void Phrase::addChild(Phrase *phrase)
{
    m_children.append(phrase);
}

void Phrase::removeChild(const QString &phrase_id)
{
    for (int i = 0; i < m_children.size(); i++)
    {
        if (phrase_id == m_children[i]->getId())
        {
            m_children.removeAt(i);
        }
    }
}

QList<Phrase*> Phrase::getAllPhrase(QList<Phrase *> &list)
{
	list.append(m_children);
    for (int i = 0; i < m_children.size(); i++)
    {
		m_children[i]->getAllPhrase(list);
    }
    return list;
}

void Phrase::addPrecondition(const Fact &fact)
{
    for (int i = 0; i < m_precondition.size(); i++)
    {
        if (m_precondition[i].getFactName() == fact.getFactName())
        {
            m_precondition[i].setFactStat(fact.getFactStat());
            return;
        }
    }
    m_precondition.append(fact);
}

void Phrase::addInform(const Fact &fact)
{
    for (int i = 0; i < m_inform.size(); i++)
    {
        if (m_inform[i].getFactName() == fact.getFactName())
        {
            m_inform[i].setFactStat(fact.getFactStat());
            return;
        }
    }
    m_inform.append(fact);
}

QDomElement Phrase::toXML(QDomDocument &doc)
{
    QDomElement ele = doc.createElement("phrase");
    ele.setAttribute("id", m_id);
    ele.setAttribute("role", m_role);
    ele.setAttribute("text", m_text);
    ele.setAttribute("associatedRoleType", m_associated_role_type);
	if (m_parent != NULL)
	{
		ele.setAttribute("parent", m_parent->getId());
	}
    QString child;
    for (int i = 0; i < m_children.size(); i++)
    {
        child = child + m_children[i]->getId()+";";
    }
    ele.setAttribute("children",child);
    QString associated_role;
    for (int i = 0; i < m_associated_role.size(); i++)
    {
        associated_role = associated_role + m_associated_role[i]+";";
    }
    ele.setAttribute("associatedRole",associated_role);
    QDomElement prec = doc.createElement("preconditions");
    for (int i = 0; i < m_precondition.size(); i++)
    {
        prec.appendChild(m_precondition[i].toXML(doc));
    }
    ele.appendChild(prec);
    QDomElement inform = doc.createElement("informs");
    for (int i = 0; i < m_inform.size(); i++)
    {
        inform.appendChild(m_inform[i].toXML(doc));
    }
    ele.appendChild(inform);
    return ele;
}

void Phrase::fromXML(QDomElement ele)
{
    m_id = ele.attribute("id", "");
    m_role = ele.attribute("role", "");
    m_text = ele.attribute("text", "");
    m_associated_role_type = (AssociatedRoleType) ele.attribute("associatedRoleType","").toInt();

    QString associated_role = ele.attribute("associatedRole","");
    if (m_associated_role_type != ALL_ROLES && associated_role != "")
    {
        m_associated_role = associated_role.split(";");
        m_associated_role.removeLast();
    }
    else
    {
        m_associated_role_type = ALL_ROLES;
    }

    QDomNode Node = ele.firstChild();
    while (!Node.isNull())
    {
        QDomElement ele = Node.toElement();
        if (ele.tagName() == "preconditions")
        {
            QDomNode PrecNode = ele.firstChild();
            while (!PrecNode.isNull())
            {
                Fact fact;
                fact.fromXML(PrecNode.toElement());
                addPrecondition(fact);
                PrecNode = PrecNode.nextSibling();
            }
        }
        else if (ele.tagName() == "informs")
        {
            QDomNode infoNode = ele.firstChild();
            while (!infoNode.isNull())
            {
                Fact fact;
                fact.fromXML(infoNode.toElement());
                addInform(fact);
                infoNode = infoNode.nextSibling();
            }
        }
		Node = Node.nextSibling();
    }
}

Phrase& Phrase::operator=(const Phrase& phrase)
{
    m_id = phrase.getId();
    m_role = phrase.getRole();
    m_inform = phrase.m_inform;
    m_precondition = phrase.m_precondition;
    m_text = phrase.getText();
    m_parent = phrase.m_parent;
    m_children.clear();
    m_children = phrase.getChildren();
    return *this;
}

}
